//============================================================================
// Name        : ex01.cpp
// Author      : Jordan Gray
// Copyright   : MIT
// Description : Stroustrup's The C++ Programming Language, exercise 01
//============================================================================

#include <iostream>

//definitions for X and Y moved into header
#include "x_and_y.h"

namespace ex01 {
extern X operator*(X,Y);
extern int f(X);

/*
 * candidate expressions (part 1)
 * X x = 1; implicit conversion of 1 to x(1) using X's constructor
 * Y y = x; implicit conversion of x to y(x) using Y's constructor
 * int i = 2; no conversion necessary I think
 */
  X x = 1; //implicit conversion of 1 to x(1) using X's constructor
  Y y = x; //implicit conversion of x to y(x) using Y's constructor
  int i = 2; //no conversion necessary I think

} // namespace

int main() {
  // using `using` as a compromise between original global ex01 and my desire to encapsulate code
  // in namespaces
  using namespace ex01;
  std::cout << "X x = " << x.i << std::endl;
  std::cout << "Y y = " << y.i << std::endl;
  std::cout << "i = " << i << std::endl;
/*
 * candidate expressions (part 2)
 * i + 10; no conversion
 * y + 10; INVALID, could either be i = int(y)+10; OR y = y+X(10);
 * y + 10 * y; INVALID: * precedence, could either be x = X(10) * y; OR i = 10 * int(y);
 * x + y + i; X X::operator+(X,int) w/ call to Y::operator int(), same operator for 2nd call
 * x * x + i; Y(X) to call X operator*(X,Y), then x+x(1)
 * f(7); implicit X(int) conversion
 * f(y); INVALID, no X(Y)
 * y+y; int(y)+int(y), since no X(Y), and only Y Y::operator+(X)
 * 106+y; y converted to int using Y::operator int() for native operator+
 */
  int tmp_int;
  X tmp_X(0);
  Y tmp_Y(tmp_X);
  tmp_int = 1+10; std::cout << "1+10=" << tmp_int << std::endl;
  tmp_X = x+y+i; std::cout << "x+y+i=" << tmp_X.i << std::endl;
  tmp_X = x*x+i; std::cout << "x+x+i=" << tmp_X.i << std::endl;
  tmp_int = f(7); std::cout << "f(7)=" << tmp_int << std::endl;
  tmp_int = y+y; std::cout << "y+y=" << tmp_int << std::endl;
  tmp_int = 106+y; std::cout << "106+y=" << tmp_int << std::endl;
  return 0;
}
